From 0f2ce2bb1c3e91d2723a1fa4d305f38629c67e98 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 30 Oct 2015 12:44:24 -0400 Subject: [PATCH] paned: Convert to CSS nodes Add a subnode for the separator, and use it for drawing. --- gtk/gtkpaned.c | 89 ++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 76 insertions(+), 13 deletions(-) diff --git a/gtk/gtkpaned.c b/gtk/gtkpaned.c index e684edbd85..d749d648a8 100644 --- a/gtk/gtkpaned.c +++ b/gtk/gtkpaned.c @@ -37,6 +37,9 @@ #include "gtkintl.h" #include "gtkwidgetprivate.h" #include "a11y/gtkpanedaccessible.h" +#include "gtkcssnodeprivate.h" +#include "gtkcssstylepropertyprivate.h" +#include "gtkstylecontextprivate.h" /** * SECTION:gtkpaned @@ -73,6 +76,11 @@ * The application can set the position of the slider as if it were set * by the user, by calling gtk_paned_set_position(). * + * # CSS nodes + * + * GtkPaned has a main CSS node with name paned, and a subnode for + * the separator with name separator. + * * ## Creating a paned widget with minimum sizes. * * |[ @@ -111,6 +119,7 @@ struct _GtkPanedPrivate GdkRectangle handle_pos; GdkWindow *handle; + GtkCssNode *handle_node; GtkGesture *pan_gesture; @@ -654,6 +663,7 @@ gtk_paned_class_init (GtkPanedClass *class) add_move_binding (binding_set, GDK_KEY_KP_End, 0, GTK_SCROLL_END); gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_PANED_ACCESSIBLE); + gtk_widget_class_set_css_name (widget_class, "paned"); } static GType @@ -768,11 +778,35 @@ pan_gesture_drag_end_cb (GtkGestureDrag *gesture, gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_DENIED); } +static void +node_style_changed_cb (GtkCssNode *node, + GtkCssStyle *old_style, + GtkCssStyle *new_style, + GtkWidget *widget) +{ + GtkBitmask *changes; + static GtkBitmask *affects_size = NULL; + + if (G_UNLIKELY (affects_size == NULL)) + affects_size = _gtk_css_style_property_get_mask_affecting (GTK_CSS_AFFECTS_SIZE | GTK_CSS_AFFECTS_CLIP); + + changes = _gtk_bitmask_new (); + changes = gtk_css_style_add_difference (changes, old_style, new_style); + + if (_gtk_bitmask_intersects (changes, affects_size)) + gtk_widget_queue_resize (widget); + else + gtk_widget_queue_draw (widget); + + _gtk_bitmask_free (changes); +} + static void gtk_paned_init (GtkPaned *paned) { GtkPanedPrivate *priv; GtkGesture *gesture; + GtkCssNode *widget_node; gtk_widget_set_has_window (GTK_WIDGET (paned), FALSE); gtk_widget_set_can_focus (GTK_WIDGET (paned), TRUE); @@ -819,6 +853,14 @@ gtk_paned_init (GtkPaned *paned) gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (gesture), GTK_PHASE_CAPTURE); priv->pan_gesture = gesture; + + widget_node = gtk_widget_get_css_node (GTK_WIDGET (paned)); + priv->handle_node = gtk_css_node_new (); + gtk_css_node_set_name (priv->handle_node, I_("separator")); + gtk_css_node_set_parent (priv->handle_node, widget_node); + gtk_css_node_set_state (priv->handle_node, gtk_css_node_get_state (widget_node)); + g_signal_connect_object (priv->handle_node, "style-changed", G_CALLBACK (node_style_changed_cb), paned, 0); + g_object_unref (priv->handle_node); } static void @@ -1722,24 +1764,12 @@ gtk_paned_draw (GtkWidget *widget, priv->child1 && gtk_widget_get_visible (priv->child1) && priv->child2 && gtk_widget_get_visible (priv->child2)) { - GtkStateFlags state; - - state = gtk_widget_get_state_flags (widget); - - if (gtk_widget_is_focus (widget)) - state |= GTK_STATE_FLAG_SELECTED; - if (priv->handle_prelit) - state |= GTK_STATE_FLAG_PRELIGHT; - - gtk_style_context_save (context); - gtk_style_context_set_state (context, state); - gtk_style_context_add_class (context, GTK_STYLE_CLASS_PANE_SEPARATOR); + gtk_style_context_save_to_node (context, priv->handle_node); gtk_render_handle (context, cr, priv->handle_pos.x - allocation.x, priv->handle_pos.y - allocation.y, priv->handle_pos.width, priv->handle_pos.height); - gtk_style_context_restore (context); } @@ -1804,6 +1834,23 @@ update_drag (GtkPaned *paned, gtk_paned_set_position (paned, size); } +static void +update_node_state (GtkWidget *widget) +{ + GtkPaned *paned = GTK_PANED (widget); + GtkPanedPrivate *priv = paned->priv; + GtkStateFlags state; + + state = gtk_widget_get_state_flags (widget); + + if (gtk_widget_is_focus (widget)) + state |= GTK_STATE_FLAG_SELECTED; + if (priv->handle_prelit) + state |= GTK_STATE_FLAG_PRELIGHT; + + gtk_css_node_set_state (priv->handle_node, state); +} + static gboolean gtk_paned_enter (GtkWidget *widget, GdkEventCrossing *event) @@ -1814,6 +1861,7 @@ gtk_paned_enter (GtkWidget *widget, if (!gtk_gesture_is_active (priv->pan_gesture)) { priv->handle_prelit = TRUE; + update_node_state (widget); gtk_widget_queue_draw_area (widget, priv->handle_pos.x, priv->handle_pos.y, @@ -1834,6 +1882,7 @@ gtk_paned_leave (GtkWidget *widget, if (!gtk_gesture_is_active (priv->pan_gesture)) { priv->handle_prelit = FALSE; + update_node_state (widget); gtk_widget_queue_draw_area (widget, priv->handle_pos.x, priv->handle_pos.y, @@ -1884,6 +1933,8 @@ gtk_paned_state_flags_changed (GtkWidget *widget, if (cursor) g_object_unref (cursor); } + + update_node_state (widget); } /** @@ -1952,6 +2003,8 @@ gtk_paned_pack1 (GtkPaned *paned, gboolean shrink) { GtkPanedPrivate *priv; + GtkCssNode *widget_node; + GtkCssNode *child_node; g_return_if_fail (GTK_IS_PANED (paned)); g_return_if_fail (GTK_IS_WIDGET (child)); @@ -1964,6 +2017,10 @@ gtk_paned_pack1 (GtkPaned *paned, priv->child1_resize = resize; priv->child1_shrink = shrink; + widget_node = gtk_widget_get_css_node (GTK_WIDGET (paned)); + child_node = gtk_widget_get_css_node (child); + gtk_css_node_insert_before (widget_node, child_node, priv->handle_node); + gtk_widget_set_parent_window (child, priv->child1_window); gtk_widget_set_parent (child, GTK_WIDGET (paned)); } @@ -1985,6 +2042,8 @@ gtk_paned_pack2 (GtkPaned *paned, gboolean shrink) { GtkPanedPrivate *priv; + GtkCssNode *widget_node; + GtkCssNode *child_node; g_return_if_fail (GTK_IS_PANED (paned)); g_return_if_fail (GTK_IS_WIDGET (child)); @@ -1997,6 +2056,10 @@ gtk_paned_pack2 (GtkPaned *paned, priv->child2_resize = resize; priv->child2_shrink = shrink; + widget_node = gtk_widget_get_css_node (GTK_WIDGET (paned)); + child_node = gtk_widget_get_css_node (child); + gtk_css_node_insert_after (widget_node, child_node, priv->handle_node); + gtk_widget_set_parent_window (child, priv->child2_window); gtk_widget_set_parent (child, GTK_WIDGET (paned)); } -- 2.30.2